﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Tzx.Utilities;

namespace Tzx.Tools.Payroll2Images.Exe.Api
{
    /// <summary>
    /// API调用
    /// </summary>
    internal class ApiCall
    {

        #region 1.提交一行发送

        /// <summary>
        /// 1.提交一行发送
        /// </summary>
        public static YesOrNo Do_SubmitSend(string filePathName, ref ApiStatus status)//, out string message
        {
            //1.上传
            string media_id = null;
            string msg_upload;
            //bool uploadOk = Do_UploadFile(filePathName, out media_id, out message);
            YesOrNo ynUploadOk = Do_UploadFile(filePathName, out media_id, out msg_upload);
            if (ynUploadOk != YesOrNo.Yes)
            {
                //上传不成功,返回了
                status.remark_text = msg_upload;
                status.status_submit_send = ynUploadOk;
                return ynUploadOk;
            }

            //文件名转职员名字符串
            string fileNameNoExt = string.Format("{0}", Path.GetFileNameWithoutExtension(filePathName));
            string[] ss = fileNameNoExt.Split('_');
            string empNameText = ss.Length > 1 ? ss[1] : fileNameNoExt;

            //2.发送
            string task_id = null;
            string send_user_id_ss = null;
            string msg2_send;
            //bool submitOk = Do_SendMedia(media_id, empNameText, out send_user_id_ss, out task_id, out message);
            YesOrNo ynSubmit = Do_SendMedia(media_id, empNameText, out send_user_id_ss, out task_id, out msg2_send);

            //log
            LogFile.Instance().LogText("已提交发送", empNameText, "task_id=" + task_id);

            //8.返回
            status.status_submit_send = ynSubmit; //来自API
            status.media_id = string.Format("{0}", media_id);//上传成功了
            status.task_id = string.Format("{0}", task_id);//发送task_id
            status.user_idss = send_user_id_ss; //拼接用户
            status.remark_text = msg2_send;
            return ynSubmit;
        }

        /// <summary>
        /// 上传文件获得media_id
        /// </summary>
        /// <param name="filePathName"></param>
        /// <param name="media_id"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private static YesOrNo Do_UploadFile(string filePathName,out string media_id,out string message)
        {
            media_id = null;
            message = null;

            //
            if (!File.Exists(filePathName))
            {
                message = "文件不存在";
                return YesOrNo.Error;
            }

            //文件名,接收人名
            string fileNameAndExt = string.Format("{0}", Path.GetFileName(filePathName));
            string fileName_EmpNameText = Path.GetFileNameWithoutExtension(filePathName);
            if (string.IsNullOrEmpty(fileName_EmpNameText))
            {
                message = "文件名不完整(接收人名等信息)";
                return YesOrNo.Error;
            }

            //1.上传文件
            //string url_upload = "http://10.10.10.89:8900/api/ding_msg/media_uploadfile.ashx?" +
            //                  API_Config.KEY_url_token +
            //                  "=" +
            //                  API_Config.Build_v10_Token();
            string url_upload = string.Format("{0}/{1}?token={2}",
                API_Config.Url_Server.TrimEnd('/'),
                API_Config.Url_1_Upload,
                API_Config.Build_v10_Token()
                );
            string[] files = new[] { filePathName };
            NameValueCollection nvc_upload = new NameValueCollection();
            nvc_upload.Add("f", fileNameAndExt);

            string json_upload;
            string errorText_upload;
            bool upload_ok = API_HttpHelp.UploadMedia(url_upload, null, nvc_upload, files, out json_upload,
                out errorText_upload);
            if (!upload_ok)
            {
                message = "上传文件错误:" + errorText_upload;
                return YesOrNo.Error;
            }
            if (string.IsNullOrEmpty(json_upload))
            {
                message = "上传文件返回空";
                return YesOrNo.Error;
            }

            //2.上传文件解析
            long errcode_upload = -9999;
            string errmsg_upload = null;
            Hashtable ht_upload_a = JsonConvert.DeserializeObject<Hashtable>(json_upload);
            if (ht_upload_a != null)
            {
                if (ht_upload_a.ContainsKey("errcode"))
                {
                    errcode_upload = (long)ht_upload_a["errcode"];
                }
                if (ht_upload_a.ContainsKey("errmsg"))
                {
                    errmsg_upload = string.Format("{0}", ht_upload_a["errmsg"]);
                }
                if (ht_upload_a.ContainsKey("media_id"))
                {
                    media_id = string.Format("{0}", ht_upload_a["media_id"]);
                }
            }
            if (errcode_upload != 0)
            {
                message = errmsg_upload;
                return YesOrNo.No;
            }
            if (string.IsNullOrEmpty(media_id))
            {
                message = "没有上传media_id";
                return YesOrNo.Error;
            }

            //9.返回
            return YesOrNo.Yes;
        }

        /// <summary>
        /// 发送文件media_id
        /// </summary>
        /// <param name="media_id"></param>
        /// <param name="empNameText"></param>
        /// <param name="send_user_id_ss"></param>
        /// <param name="task_id"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private static YesOrNo Do_SendMedia(string media_id, string empNameText, 
            out string send_user_id_ss, out string task_id, out string message)
        {
            send_user_id_ss = null;
            task_id = null;

            //2.发送消息文件
            string url_submit = string.Format("{0}/{1}?token={2}&to={3}",
                API_Config.Url_Server.TrimEnd('/'),
                API_Config.Url_1_send.TrimStart('/'),
                API_Config.Build_v10_Token(),
                empNameText
                );
            Hashtable ht_post_submit = new Hashtable()
            {
                {"msgtype", "image"},
                {
                    "image",new Hashtable()
                    {
                        {"media_id", media_id},
                    }
                },
            };
            string post_json_submit = JsonConvert.SerializeObject(ht_post_submit);

            //访问api
            string okJson_submit;
            string errorText_submit;
            bool post_ok = API_HttpHelp.PostFunction(url_submit, post_json_submit, null, "POST", out okJson_submit, out errorText_submit);
            if (!post_ok)
            {
                message = "提交发送失败:" + errorText_submit;
                LogFile.Instance().LogText(empNameText, message);
                return YesOrNo.Error;
            }

            //2.发送消息文件解析
            long errcode_submit = -9999;
            string errmsg_submit = null;
            List<string> send_user_id_list = new List<string>();

            Hashtable ht_submit_a = JsonConvert.DeserializeObject<Hashtable>(okJson_submit);
            if (ht_submit_a == null)
            {
                message = "解析发送返回Hashtable为空";
                LogFile.Instance().LogText(empNameText, message);
                return YesOrNo.Error;
            }

            //解析
            if (ht_submit_a.ContainsKey("errcode"))
            {
                errcode_submit = (long) ht_submit_a["errcode"];
            }
            if (ht_submit_a.ContainsKey("errmsg"))
            {
                errmsg_submit = string.Format("{0}", ht_submit_a["errmsg"]);
            }
            if (ht_submit_a.ContainsKey("task_id"))
            {
                task_id = string.Format("{0}", ht_submit_a["task_id"]);
            }
            if (ht_submit_a.ContainsKey("send_user_id_list"))
            {
                Newtonsoft.Json.Linq.JArray user_id_ss =
                    (Newtonsoft.Json.Linq.JArray) ht_submit_a["send_user_id_list"];
                foreach (JToken jToken in user_id_ss)
                {
                    send_user_id_list.Add(string.Format("{0}", jToken));
                }
            }

            //返回
            message = string.Format("{0}",errmsg_submit);
            YesOrNo yn = (errcode_submit == 0 ? YesOrNo.Yes : YesOrNo.No);
            if (yn == YesOrNo.No)
            {
                //钉钉api返回失败
                message = "钉钉api返回失败," + errmsg_submit;
                LogFile.Instance().LogText(empNameText, errcode_submit.ToString(), message);
            }

            if (string.IsNullOrEmpty(task_id))
            {
                message = "没有task_id";
                LogFile.Instance().LogText(empNameText, errcode_submit.ToString(), message);
                return YesOrNo.Error;
            }

            //发送userid
            send_user_id_ss = string.Join(",", send_user_id_list).Trim(',');

            //返回
            return yn;
        }

        #endregion

        /// <summary>
        /// 2.获取更新消息发送进度(一行)
        /// </summary>
        public static YesOrNo Do_GetSendProgress(ref ApiStatus status)//, out string message
        {
            //url
            string task_id = status.task_id;
            string url = string.Format("{0}/{1}?token={2}&task_id={3}",
                API_Config.Url_Server.TrimEnd('/'),
                API_Config.Url_2_progress.TrimStart('/'),
                API_Config.Build_v10_Token(),
                task_id
                );

            //文件名
            string fileName = status.file_short_name;

            //访问api
            string okJson;
            string errorText;
            bool post_ok = API_HttpHelp.PostFunction(url, null, null, "POST", out okJson, out errorText);
            if (!post_ok)
            {
                string message = "访问进度失败:" + errorText;
                LogFile.Instance().LogText(fileName, message);
                status.status_progress = YesOrNo.Error;
                status.remark_text = message;
                return YesOrNo.Error;
            }

            //解析
            Hashtable ht_a = JsonConvert.DeserializeObject<Hashtable>(okJson);
            if (ht_a == null)
            {
                string message2 = "进度返回解析Hashtable为空";
                LogFile.Instance().LogText(fileName, message2, okJson);
                status.status_progress = YesOrNo.Error;
                status.remark_text = message2;
                return YesOrNo.Error;
            }

            ZBug.Log("okJson", "\n", okJson);

            //解析
            long errcode = -9999;
            string errmsg = null;
            long? progress_percent = null;
            long? progress_status = null;
            if (ht_a.ContainsKey("errcode"))
            {
                errcode = (long) ht_a["errcode"];
            }
            if (ht_a.ContainsKey("errmsg"))
            {
                errmsg = string.Format("{0}", ht_a["errmsg"]);
            }
            if (ht_a.ContainsKey("percent"))
            {
                //百分比percent,0~100,
                progress_percent = (long) ht_a["percent"];
            }
            if (ht_a.ContainsKey("status"))
            {
                //状态status,0未开始,1处理中,2处理完毕,
                progress_status = (long) ht_a["status"];
            }

            //
            if (errcode != 0)
            {
                string message3 = string.Format("{0},{1}", errcode, errmsg);
                LogFile.Instance().LogText("进度返回", fileName, message3);
                status.status_progress = YesOrNo.No;
                status.remark_text = message3;
                return YesOrNo.No;
            }

            //返回
            string status_text = "#";
            if (progress_status.HasValue)
            {
                switch (progress_status.Value)
                {
                    case 0:
                        status_text = "未开始";
                        break;
                    case 1:
                        status_text = "处理中";
                        break;
                    case 2:
                        status_text = "处理完毕";
                        break;
                    default:
                        status_text = progress_status.Value.ToString();
                        break;
                }
            }

            //返回
            bool sendOk = (progress_percent.HasValue && progress_percent.Value == 100) &&
                          (progress_status.HasValue && progress_status.Value == 2);
            string message_progress = string.Format("{0}%,{1}", progress_percent, status_text);

            YesOrNo yn = sendOk ? YesOrNo.Yes : YesOrNo.No;
            status.status_progress = yn;
            status.remark_text = message_progress;
            return yn;
        }

        /// <summary>
        /// 3.获取一个更新消息发送结果(阅读状态等),返回获取是否完成 
        /// </summary>
        public static YesOrNo Do_GetResult_IsReaded(ref ApiStatus status)//, out string message
        {
            //user_id
            string user_id = null;
            string[] user_idss =
                string.Format("{0}", status.user_idss).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (user_idss.Length > 0)
            {
                user_id = user_idss[0];//TODO:只检测第一个
            }
            if (string.IsNullOrEmpty(user_id))
            {
                string message = "当前无关联用户id";
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message;
                return YesOrNo.Error;
            }

            //url
            string task_id = status.task_id;
            string url = string.Format("{0}/{1}?token={2}&task_id={3}",
                API_Config.Url_Server.TrimEnd('/'),
                API_Config.Url_3_result.TrimStart('/'),
                API_Config.Build_v10_Token(),
                task_id
                );

            //访问api
            string okJson;
            string errorText;
            bool post_ok = API_HttpHelp.PostFunction(url, null, null, "POST", out okJson, out errorText);
            if (!post_ok)
            {
                string message3 = "访问结果状态失败:" + errorText;
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message3;
                return YesOrNo.Error;
            }

            //解析
            JSON_MessageAsyncSend_3_result json_result = JsonConvert.DeserializeObject<JSON_MessageAsyncSend_3_result>(okJson);
            if (json_result == null)
            {
                string message4 = "解析结果状态错误";
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message4;
                return YesOrNo.Error;
            }
            if (json_result.errcode != 0)
            {
                string message5 = "错误," + json_result.errmsg;
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message5;
                return YesOrNo.Error;
            }
            if (json_result.send_result == null)
            {
                string message6 = "结果为空";
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message6;
                return YesOrNo.Error;
            }
            if (json_result.send_result.errcode != 0)
            {
                string message7 = "错误," + json_result.send_result.errmsg;
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message7;
                return YesOrNo.Error;
            }
            if (json_result.send_result.send_result == null)
            {
                string message8 = "结果为空";
                status.status_result_read = YesOrNo.Error;
                status.remark_text = message8;
                return YesOrNo.Error;
            }

            //已读未读
            string[] readed = json_result.send_result.send_result.read_user_id_list;
            string[] unread = json_result.send_result.send_result.unread_user_id_list;
            if (readed.Length > 0)
            {
                if (Array.IndexOf(readed, user_id) > -1)
                {
                    status.remark_text = "已读";
                    status.status_result_read = YesOrNo.Yes;
                    return YesOrNo.Yes;//已读
                }
            }
            if (unread.Length > 0)
            {
                if (Array.IndexOf(unread, user_id) > -1)
                {
                    status.remark_text = "未读";
                    status.status_result_read = YesOrNo.No;
                    return YesOrNo.No;//未读
                }
            }

            //其它错误状态,记录日志
            LogFile.Instance().LogText("user_id=" + user_id, okJson);
            StringBuilder sb = new StringBuilder();
            if (json_result.send_result.send_result.failed_user_id_list.Length > 0)
            {
                sb.Append("用户发送失败,");
            }
            if (json_result.send_result.send_result.forbidden_user_id_list.Length > 0)
            {
                sb.Append("用户被禁,");
            }
            if (json_result.send_result.send_result.invalid_user_id_list.Length > 0)
            {
                sb.Append("用户id无效,");
            }

            //返回
            status.remark_text = sb.ToString();
            status.status_result_read = YesOrNo.Error;
            return YesOrNo.Error;
        }

        /// <summary>
        /// 4.撤回一个消息
        /// </summary>
        public static YesOrNo Do_Recall(ref ApiStatus status) //, out string message
        {
            //url
            string task_id = status.task_id;
            string url = string.Format("{0}/{1}?token={2}&task_id={3}",
                API_Config.Url_Server.TrimEnd('/'),
                API_Config.Url_4_recall.TrimStart('/'),
                API_Config.Build_v10_Token(),
                task_id
                );

            //访问api
            string okJson;
            string errorText;
            bool post_ok = API_HttpHelp.PostFunction(url, null, null, "POST", out okJson, out errorText);
            if (!post_ok)
            {
                string message2 = "撤回失败:" + errorText;
                status.status_recall = YesOrNo.Error;
                status.remark_text = message2;
                return YesOrNo.Error;
            }

            //解析
            long errcode = -9999;
            string errmsg = null;
            Hashtable ht_a = JsonConvert.DeserializeObject<Hashtable>(okJson);
            if (ht_a == null)
            {
                string message3 = "撤销返回信息为空";
                status.status_recall = YesOrNo.Error;
                status.remark_text = message3;
                return YesOrNo.Error;
            }

            if (ht_a.ContainsKey("errcode"))
            {
                errcode = (long) ht_a["errcode"];
            }
            if (ht_a.ContainsKey("errmsg"))
            {
                errmsg = string.Format("{0}", ht_a["errmsg"]);
            }

            //返回
            YesOrNo yn = errcode == 0 ? YesOrNo.Yes : YesOrNo.No;
            string message8 = string.Format("{0},{1}", errcode, errmsg);
            status.status_recall = yn;
            status.remark_text = string.Format("{0},{1}", (errcode == 0 ? "已撤回" : "撤回失败"), message8);
            return yn;
        }

    }
}